package com.df.ez_game.server.logic.status_sync;

import com.df.ez_game.business.annotation.EzController;
import com.df.ez_game.server.PushMsgMeta;
import com.df.ez_game.server.req_metadata.ControllerMetadatas;
import com.df.ez_game.tools.EzUtils;
import lombok.Data;

import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class CodeGenerator {
    //请求元数据
    private static ControllerMetadatas metadatas = new ControllerMetadatas();
    //广播id和类型的映射
    private static Map<Integer, PushMsgMeta> pushMsgMap = new HashMap<>();
    //异常信息
    private static Map<Integer, String> exceptionMeta = new HashMap<>();

    private static Set<ProtoEntity> protoEntity = new HashSet();
    @Data
    public static class ProtoEntityField{
        private String type;
        private String name;
        private Integer index;
    }
    @Data
    public static class ProtoEntity{
        private String entityName;
        List<ProtoEntityField> fields = new ArrayList<>();
    }

    public static void main(String[] args) throws Exception {
        Set<Class<?>> classes = scanPackage("com.df.ez_game.server.logic.status_sync", clazz -> {
            EzController annotation = clazz.getAnnotation(EzController.class);
            if (annotation == null) {
                return false;
            }
            return true;
        });
        System.out.println(1);
        //扫描请求数据
        metadatas.parserGeneratorControllers(classes);

        //收集实体
        EzUtils.protoEntityCollect(metadatas.protoClasses(),protoEntity);
        //扫描推送数据
        Set<Class> enumClasses = new HashSet<>();
        enumClasses.add(SyncPushMsgEnum.class);
        EzUtils.pushEnumsHandle(enumClasses,pushMsgMap);
        //扫描异常信息
        Set<Class> exceptionClasses = new HashSet<>();
        exceptionClasses.add(SyncExceptions.class);
        EzUtils.exceptionDataHandle(exceptionClasses,exceptionMeta);


        //proto路径
        //代码路径：
        //   api:
        //      base
        //          EzGameNet.ts
        //          EzGameNetManager.ts
        //          EzGameNetReqInstance.ts
        //          EzGameUtils.ts
        //      pb(文件夹)
        //          ezgame_pb.ts
        //          xx_pb.ts
        //      XXApi.ts
        //      XXMsgEnum.ts
        //生产cocos 前端代码
        String codeRootPath = "D:\\My\\project\\java\\ioGame-ioGame17\\ez_game\\generator_out\\cocos";
        //1.前端核心代码
        //拷贝核心代码到文件夹

        //2.protobuf文件
        //业务产生的类
        Map<String,String> javaType2ProtoType = new HashMap<>();
//        javaType2ProtoType.put("")
        //3.前端api文件
        //4.前端推送消息监听文件
        //5.前端异常信息映射文件

        //生成rpc文件（每个服对其他服开放的api最好集中到一个类或几个类）
    }
    public static Set<Class<?>> scanPackage(String packageName, Predicate<Class<?>> filter) throws Exception {
        Set<Class<?>> classes = new HashSet<>();
        String path = packageName.replace('.', '/');
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Enumeration<URL> resources = classLoader.getResources(path);

        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            if (resource.getProtocol().equals("file")) {
                String filePath = URLDecoder.decode(resource.getFile(), StandardCharsets.UTF_8);
                scanDirectory(new File(filePath), packageName, classes);
            } else if (resource.getProtocol().equals("jar")) {
                // 简化处理：此处略去 JAR 扫描逻辑（较复杂）
                // 实际项目建议用 Reflections 或 Spring
                System.err.println("JAR scanning not implemented in this example.");
            }
        }
        if(filter!=null){
            classes = classes.stream().filter(filter).collect(Collectors.toSet());
        }
        return classes;
    }

    private static void scanDirectory(File dir, String packageName, Set<Class<?>> classes) {
        File[] files = dir.listFiles();
        if (files == null) return;

        for (File file : files) {
            if (file.isDirectory()) {
                scanDirectory(file, packageName + "." + file.getName(), classes);
            } else if (file.getName().endsWith(".class")) {
                String className = packageName + "." + file.getName().substring(0, file.getName().length() - 6);
                try {
                    classes.add(Class.forName(className));
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
